﻿using System;
using System.Collections.Generic;

namespace Ukagaka.Named.Ghost.SakuraScript
{
	/// <summary>
	/// マークアップを表現します
	/// </summary>
	[Serializable]
	public class Markup
	{
		/// <summary>
		/// リーダ文字群を取得します
		/// </summary>
		private static readonly HashSet<char> Leaders = new HashSet<char>( @"%\" );

		/// <summary>
		/// マークアップ文字群を取得します
		/// </summary>
		private static readonly HashSet<char> MarkupChars = new HashSet<char>( @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!*-+&?()/" );

		/// <summary>
		/// リーダを表現します
		/// </summary>
		public char Leader
		{
			get;
			private set;
		}

		/// <summary>
		/// マークアップ名を取得します
		/// </summary>
		public string Name
		{
			get;
			private set;
		}

		/// <summary>
		/// マークアップを表現するインスタンスを作成します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		public Markup( string markup )
			: this( markup[ 0 ], markup.Substring( 1 ) )
		{
			// do nothing
		}

		/// <summary>
		/// マークアップを表現するインスタンスを作成します
		/// </summary>
		/// <param name="leader">リーダ</param>
		/// <param name="name">マークアップ名</param>
		public Markup( char leader, string name )
		{
			Leader = leader;
			Name = name;
		}

		/// <summary>
		/// マークアップを取得します
		/// </summary>
		/// <returns></returns>
		public override string ToString( )
		{
			return string.Concat( Leader, Name );
		}

		/// <summary>
		/// 文字がリーダ文字かどうかを取得します
		/// </summary>
		/// <param name="c">文字</param>
		/// <returns>文字がリーダ文字かどうか</returns>
		public static bool IsLeader( char c )
		{
			return Leaders.Contains( c );
		}

		/// <summary>
		/// 文字がマークアップ文字かどうかを取得します
		/// </summary>
		/// <param name="c">文字</param>
		/// <returns>文字がマークアップ文字かどうか</returns>
		public static bool IsMarkupChar( char c )
		{
			return Markup.IsLeader( c ) || MarkupChars.Contains( c );
		}
	}
}
